package server

import (
	"context"
	"github.com/spf13/cast"
	"longmen/server/config/global"
	"longmen/server/internal/services/nami/services/sports/basketball"
	"longmen/server/internal/services/nami/services/sports/basketball/bbcache"
	"longmen/server/internal/services/nami/services/sports/football"
	"longmen/server/internal/services/nami/services/sports/football/fbcache"
	_const "longmen/server/pkg/common/helper/const"
	pb "longmen/server/pkg/protobuf"
)

const (
	CodeSuccess         = 0
	CodeSportIdInvalid  = 1
	CodeMatchIdNotFound = 2

	MsgSuccess         = "OK"
	MsgSportIdInvalid  = "未找到该赛事"
	MsgMatchIdNotFound = "不支持该赛事类型"
)

func (s *Server) GetLineupByMatch(ctx context.Context, req *pb.GetLineupByMatchReq) (*pb.GetLineupByMatchResp, error) {
	var lineup *pb.Lineup
	switch req.SportId {
	case _const.FOOT_BALL_SPORT_ID:
		// 查询 es,
		esLineup, ok := football.QueryEsByMatch(int(req.MatchId))
		if !ok {
			return LineupFailResp(CodeMatchIdNotFound, MsgSportIdInvalid), nil
		}

		// es数据 -> proto数据
		lineup = &pb.Lineup{
			SportId:               req.SportId,
			MatchId:               req.MatchId,
			HomeFormationFootball: esLineup.HomeFormation,
			AwayFormationFootball: esLineup.AwayFormation,
			HomePlayersFootball:   LineupEsToProtoFootballBatch(esLineup.Home),
			AwayPlayersFootball:   LineupEsToProtoFootballBatch(esLineup.Away),
		}
	case _const.BASKET_BALL_SPORT_ID:
		// 查询 es,
		esLineup, ok := basketball.QueryEsByMatch(int(req.MatchId))
		if !ok {
			return LineupFailResp(CodeMatchIdNotFound, MsgSportIdInvalid), nil
		}

		// es数据 -> proto数据
		lineup = &pb.Lineup{
			SportId:               req.SportId,
			MatchId:               req.MatchId,
			HomePlayersBasketball: LineupEsToProtoBasketballBatch(esLineup.Home),
			AwayPlayersBasketball: LineupEsToProtoBasketballBatch(esLineup.Away),
		}
	default:
		return LineupFailResp(CodeSportIdInvalid, MsgMatchIdNotFound), nil
	}

	return LineupSuccessResp(lineup), nil
}

func LineupEsToProtoFootball(item *fbcache.LineUpItem) *pb.LineupPlayerFootball {
	result := &pb.LineupPlayerFootball{
		PlayerId: uint32(item.ID),
		Name:     item.Name,
		Number:   cast.ToString(item.ShirtNumber),
		Logo:     item.Logo,
		First:    uint32(item.First),
		Captain:  uint32(item.Captain),
		Position: item.Position,
		X:        int32(item.X),
		Y:        int32(item.Y),
		Rating:   item.Rating,
		TeamId:   uint32(item.TeamID),
	}
	return result
}

func LineupEsToProtoFootballBatch(items []fbcache.LineUpItem) []*pb.LineupPlayerFootball {
	results := make([]*pb.LineupPlayerFootball, len(items))
	for i := 0; i < len(items); i++ {
		results[i] = LineupEsToProtoFootball(&items[i])
	}
	return results
}

func LineupEsToProtoBasketball(item *bbcache.Player) *pb.LineupPlayerBasketball {
	// 根据 lang 配置, 决定用 哪个 name.
	// 规则: 指定 中文 用 中文, 否则 都用 英文 (其它 语言 在 ES 可能有 缺失).
	lang := global.Lang.GetLang()
	var name string
	if lang == _const.LangChinese { // 中文
		name = item.NameZh
	} else { // 非中文都用 英文.
		name = item.NameEn
	}

	result := &pb.LineupPlayerBasketball{
		PlayerId: uint32(item.Id),
		Name:     name,
		Number:   item.Number,
		Logo:     item.Logo,
	}

	return result
}

func LineupEsToProtoBasketballBatch(items []bbcache.Player) []*pb.LineupPlayerBasketball {
	results := make([]*pb.LineupPlayerBasketball, len(items))
	for i := 0; i < len(items); i++ {
		results[i] = LineupEsToProtoBasketball(&items[i])
	}
	return results
}

func LineupSuccessResp(lineup *pb.Lineup) *pb.GetLineupByMatchResp {
	result := &pb.GetLineupByMatchResp{
		Code:    CodeSuccess,
		Message: MsgSuccess,
		Lineup:  lineup,
	}
	return result
}

func LineupFailResp(code int, msg string) *pb.GetLineupByMatchResp {
	result := &pb.GetLineupByMatchResp{
		Code:    int32(code),
		Message: msg,
		Lineup:  nil,
	}
	return result
}
